Comp.lang.c ++ üzerinde C ++ / STL'nin Gizli Özellikleri ve Karanlık Köşelerini okuduktan sonra, aşağıdaki kod parçacığının hem Visual Studio 2008 hem de G ++ 4.4'te derlenip çalışmasına şaşırdım. İşte kod: #includeint main () { int x = 10; while (x -> 0) // x 0'a gider { printf ("% d", x); } } Çıktı: 9 8 7 6 5 4 3 2 1 0 GCC'de de çalıştığı için bunun C olduğunu varsayıyorum. Bu standartta nerede tanımlanmıştır ve nereden gelmiştir?
2020-12-07 21:25:22
-> bir operatör değildir. Aslında iki ayrı operatördür - ve>. Koşulun kodu, x'in orijinal (azaltılmamış) değerini döndürürken x'i azaltır ve ardından orijinal değeri> operatörünü kullanarak 0 ile karşılaştırır. Daha iyi anlamak için ifade şu şekilde yazılabilir: süre ((x--)> 0) | Veya tamamen farklı bir şey için ... x, 0'a kayar. süre (x - \ \ \ \ > 0) printf ("% d", x); O kadar matematiksel değil, ama ... her resim bin kelimeyi boyar ... | Bu çok karmaşık bir operatör, bu nedenle ISO / IEC JTC1 (Ortak Teknik Komite 1) bile açıklamasını C ++ Standardının iki farklı bölümüne yerleştirdi. Şaka bir yana, bunlar iki farklı operatördür: - ve> sırasıyla C ++ 03 Standardının §5.2.6 / 2 ve §5.9'da açıklanmıştır. | Eşdeğeri süre (x--> 0) x-- (azaltma sonrası) x = x-1'e eşdeğerdir, bu nedenle kod şu şekle dönüşür: while (x> 0) { x = x-1; // mantık } x--; // x <= 0 olduğunda gönderi eksiltme yapılır | x ters yönde sıfıra daha da hızlı gidebilir: int x = 10; süre (0 <---- x) { printf ("% d", x); } 8 6 4 2 Hızı bir okla kontrol edebilirsiniz! int x = 100; while (0 <-------------------- x) { printf ("% d", x); } 90 80 70 60 50 40 30 20 10 ;) | Onun #includeint main (void) { int x = 10; while (x--> 0) {// x 0'a gider printf ("% d", x); } dönüş 0; } Sadece boşluk her şeyi komik gösterir - eksiltmeler ve> karşılaştırmalar. | -> kullanımının tarihsel önemi vardır. Azaltma, x86 mimarisinde artıştan daha hızlıydı (ve bazı durumlarda hala öyle). -> kullanılması, x'in 0'a gideceğini önerir ve matematiksel geçmişi olanlara hitap eder. | süre (x--> 0) bu nasıl ayrıştırılır. | Tamamen inek, ama bunu kullanacağım: # tanımla; while int main (int argc, char * argv []) { int n = atoi (argv [1]); do printf ("n,% d \ n", n) as (n -> 0); dönüş 0; } | Okuduğum bir kitap (hangi kitabı doğru hatırlamıyorum) şunu söylüyordu: Derleyiciler sol sağ kuralı kullanarak ifadeleri en büyük simgeye göre çözümlemeye çalışıyorlar. Bu durumda ifade: x -> 0 En büyük jetonlara ayrıştırılır: simge 1: x simge 2: - simge 3:> simge 4: 0 sonuç: x--> 0 Aynı kural bu ifade için de geçerlidir: a ----- b Ayrıştırdıktan sonra: simge 1: a simge 2: - simge 3: - simge 4: - simge 5: b sonuç: (a -) - - b Umarım bu, karmaşık ifadeyi anlamaya yardımcı olur ^^ | Bu tamamen aynı süre (x--) { printf ("% d", x); } negatif olmayan sayılar için | Her neyse, artık bir "gider" operatörümüz var. "->" bir yön olarak hatırlanması kolaydır ve "x sıfıra giderken" anlamı-düzdür. Ayrıca, bazı platformlarda "for (x = 10; x> 0; x -)" den biraz daha etkilidir. | Bu kod önce x ve 0'ı karşılaştırır ve sonra x'i azaltır. (İlk yanıtta ayrıca şunu da belirtiyor: x'i sonradan azaltıyorsunuz ve sonra x ve 0'ı> operatörüyle karşılaştırıyorsunuz.) Bu kodun çıktısına bakın: 9 8 7 6 5 4 3 2 1 0 Şimdi çıktıda 0 görerek önce karşılaştırıp sonra azaltıyoruz. Önce düşürmek ve sonra karşılaştırmak istiyorsak, bu kodu kullanın: #include int main (void) { int x = 10; while (--x> 0) // x 0'a gider { printf ("% d", x); } dönüş 0; } Bu çıktı: 9 8 7 6 5 4 3 2 1 | Bu kodu çalıştırdığımda derleyicim 9876543210'u yazdıracak. #include int main () { int x = 10; while (x -> 0) // x 0'a gider { std :: cout << x; } } Beklenildiği gibi. While (x--> 0) aslında while (x> 0) anlamına gelir. X-- postu x'i azaltır. süre (x> 0) { x--; std :: cout << x; } aynı şeyi yazmanın farklı bir yoludur. Yine de orijinalin "x 0'a giderken" gibi görünmesi güzel. | - ve> arasında eksik boşluk var. x sonradan azaltılır, yani x> 0? koşulu kontrol edildikten sonra azaltılır. | - eksiltme operatörü ve> büyüktür operatörüdür. İki operatör -> gibi tek bir operatör olarak uygulanır. | İki operatörün birleşimidir. Birincisi - değeri azaltmak içindir ve> değerin sağdaki işlenenden büyük olup olmadığını kontrol etmek içindir. #include int main () { int x = 10; süre (x--> 0) printf ("% d", x); dönüş 0; } Çıktı şu şekilde olacaktır: 9 8 7 6 5 4 3 2 1 0 | Aslında, x eksilme işlemidir ve bu koşulla kontrol edilmektedir. Değil ->, (x--)> 0 Not: x'in değeri, eksilme sonrası olduğu için koşul kontrol edildikten sonra değiştirilir. Bazı benzer durumlar da ortaya çıkabilir, örneğin: -> x -> 0 ++> x ++> 0 -> = x -> = 0 ++> = x ++> = 0 | C ve C ++ "maksimum munch" kuralına uyar. Aynı şekilde a --- b, (a--) - b'ye çevrilir, sizin durumunuzda x -> 0 (x -)> 0'a çevrilir. Kuralın esas olarak söylediği şey, soldan sağa doğru, geçerli bir ifade oluşturacak maksimum karakter sayısı alınarak ifadelerin oluşturulduğudur. | Neden bu kadar karışıklık? Orijinal sorunun basit cevabı şudur: #include int main () { int x = 10; while (x>0) { printf ("% d", x); x = x-1; } } Aynı şeyi yapıyor. Bunu böyle yapmalısın demiyorum ama aynı şeyi yapıyor ve soruyu tek bir gönderide cevaplamış olur. X-- yukarıdakinin kısaltmasıdır ve> normalden büyükten büyük bir operatördür. Büyük bir gizem yok! Günümüzde basit şeyleri karmaşık hale getiren çok fazla insan var;) | Geleneksel şekilde while döngüsü parantezinde () bir koşul ve küme parantezleri {} içinde bir sonlandırma koşulu tanımlardık, ancak -> her ikisini aynı anda tanımlar. Örneğin: int abc (geçersiz) { int a = 5 while ((a--)> 0) // İkisini birden azalt ve karşılaştır { // Kod } } Bu, a'yı azaltır ve a, 0'dan büyükken döngüyü çalıştırır. Geleneksel olarak şu şekilde olacaktır: int abc (geçersiz) { int a = 5; süre (a> 0) { a--; // Kod } a--; } Her iki şekilde de aynı şeyi yapıyoruz ve aynı hedeflere ulaşıyoruz. | (x -> 0), (x--> 0) anlamına gelir. (X ->) Çıkışını kullanabilirsiniz: 9 8 7 6 5 4 3 2 1 0 Kullanabilirsiniz (- x> 0) Bu ortalama (--x> 0) Çıktı: 9 8 7 6 5 4 3 2 1 Kullanabilirsiniz (- \ \ x> 0) Çıkış: 9 8 7 6 5 4 3 2 1 Kullanabilirsiniz (\ \ x -> 0) Çıkış: 9 8 7 6 5 4 3 2 1 0 Kullanabilirsiniz (\ \ x -> 0 \ \ ) Çıkış: 9 8 7 6 5 4 3 2 1 0 Ayrıca kullanabilirsiniz ( x -> ) Çıkış: 9 8 7 6 5 4 3 2 1 0 Aynı şekilde, bu komutu başarıyla yürütmek için birçok yöntemi deneyebilirsiniz. | İşte - tekli sonradan eksiltme operatörü. while (x--> 0) // x 0'a gider { printf ("% d", x); } Başlangıçta durum şu şekilde değerlendirilecektir: (x> 0) // 10> 0 Şimdi koşul doğru olduğu için, azaltılmış bir değerle döngüye girecek x-- // x = 9 Bu yüzden ilk basılan değer 9 Ve bunun gibi. Son döngüde x = 1, dolayısıyla koşul doğrudur. Tekli operatöre göre, değer yazdırma sırasında x = 0 olarak değiştirildi. Şimdi, x = 0, koşulu (x> 0) yanlış olarak değerlendirir ve while döngüsü çıkar. | Bu -> hiç bir operatör değildir. -> gibi bir operatörümüz var ama -> gibi değil. Bu sadece while (x--> 0) 'ın yanlış bir yorumudur, bu da x'in son azaltma operatörüne sahip olduğu ve bu döngü sıfırdan büyük olana kadar çalışacağı anlamına gelir. Bu kodu yazmanın başka bir basit yolu while (x--) olacaktır. While döngüsü yanlış bir koşul aldığında durur ve burada sadece bir durum vardır, yani 0. Yani x değeri sıfıra düştüğünde duracaktır. | Oldukça aktif soru. Bu soruyu cevaplamak için 10 itibar kazanın. İtibar koşulu, bu sorunun istenmeyen postalardan ve yanıtlanmayan etkinliklerden korunmasına yardımcı olur. Aradığın cevap değil mi? C ++ c operatörleri kod formatlama standartlarına uygunluk etiketli diğer sorulara göz atın veya kendi sorunuzu sorun.